
/**
 * @file main
 *
 */

/*********************
 *      INCLUDES
 *********************/
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>

#include "lv_conf.h"
#include "lv_drv_conf.h"
#include "lvgl.h"

#if USE_WINDOWS
#include "lv_drivers/win_drv.h"
#include <windows.h>
#else
#include "lv_drivers/qt5/lv_qt5.h"
#include <QApplication>
#include <QObject>
#include <QThread>
#include "server_thread.h"
#endif // USE_WINDOWS

/*********************
 *      DEFINES
 *********************/

/**********************
 *      TYPEDEFS
 **********************/

/**********************
 *  STATIC PROTOTYPES
 **********************/
static void hal_init(void);

/**********************
 *  STATIC VARIABLES
 **********************/

/**********************
 *      MACROS
 **********************/

/**********************
 *   GLOBAL FUNCTIONS
 **********************/
#if USE_LV_EXAMPLE
void lv_example_keyboard_1(void);
void lv_example_calendar_1(void);
#endif

#if USE_WINDOWS
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int nCmdShow)
#else
#undef main
int main(int argc, char** argv)
#endif // USE_WINDOWS
{
#if USE_QT5
    QApplication app(argc, argv);
    QApplication::setOrganizationName("ISD Simulator");
    QApplication::setApplicationName("ISD Simulator");
#endif // USE_QT5

    /*Initialize LittlevGL*/
    lv_init();
    /*Initialize the HAL for LittlevGL*/
    hal_init();

    QThread *svc_thread = new QThread;
    ServerThread *vd_server = new ServerThread(nullptr);
    vd_server->moveToThread(svc_thread);
    QObject::connect(svc_thread, &QThread::started, vd_server, &ServerThread::startSVC);
    svc_thread->start();

#if USE_QT5
    return app.exec();
#else
    return 0;
#endif // USE_QT5
}

/**********************
 *   STATIC FUNCTIONS
 **********************/

/**
 * A task to measure the elapsed time for LittlevGL
 * @param data unused
 * @return never return
 */
#if !USE_WINDOWS
#if LV_TICK_CUSTOM == 1
static int tick_thread(void *data)
{
    while(1) {
        lv_tick_inc(1);
        SDL_Delay(1);   /*Sleep for 1 millisecond*/
    }

    return 0;
}
#endif
#endif // USE_WINDOWS

static lv_color_t buf1_1[QT_HOR_RES * 20];                      /*A buffer for 20 rows*/
static lv_color_t buf1_2[QT_HOR_RES * 20];                      /*A buffer for 20 rows*/
/**
 * Initialize the Hardware Abstraction Layer (HAL) for the Littlev graphics library
 */
static void hal_init(void)
{
    lv_disp_t *disp;
    static lv_disp_draw_buf_t disp_draw_buf_1;

    lv_disp_draw_buf_init(&disp_draw_buf_1, buf1_1, buf1_2, QT_HOR_RES * 20);   /*Initialize the display buffer*/

#if !USE_WINDOWS
    /* Add a display */
#if USE_QT5
    qt5_init();

    static lv_disp_drv_t disp_drv;
    lv_disp_drv_init(&disp_drv);            /*Basic initialization*/
    /*Set the resolution of the display*/
    disp_drv.hor_res = QT_HOR_RES;
    disp_drv.ver_res = QT_VER_RES;

    // disp_drv.full_refresh = 1;

    /*Used to copy the buffer's content to the display*/
    disp_drv.flush_cb = qt5_display_flush;

    /*Set a display buffer*/
    disp_drv.draw_buf = &disp_draw_buf_1;

    disp = lv_disp_drv_register(&disp_drv);
    if (disp == NULL) {
        printf("disp drv register fail\n");
    }
    lv_theme_t *theme = lv_theme_default_init(disp, lv_palette_main(LV_PALETTE_BLUE), lv_palette_main(LV_PALETTE_RED), LV_THEME_DEFAULT_DARK, LV_FONT_DEFAULT);
    lv_disp_set_theme(disp, theme);

    lv_group_t *group = lv_group_create();
    lv_group_set_default(group);

    /* Add the mouse (or touchpad) as input device */
    static lv_indev_drv_t indev_drv_mouse;
    lv_indev_drv_init(&indev_drv_mouse);          /*Basic initialization*/
    indev_drv_mouse.type = LV_INDEV_TYPE_POINTER;
    indev_drv_mouse.read_cb = qt5_mouse_read;         /*This function will be called periodically (by the library) to get the mouse position and state*/
    lv_indev_t *mouse_indev = lv_indev_drv_register(&indev_drv_mouse);

    static lv_indev_drv_t indev_drv_kb;
    lv_indev_drv_init(&indev_drv_kb); /*Basic initialization*/
    indev_drv_kb.type = LV_INDEV_TYPE_KEYPAD;
    indev_drv_kb.read_cb = qt5_keyboard_read;
    lv_indev_t *kb_indev = lv_indev_drv_register(&indev_drv_kb);
    lv_indev_set_group(kb_indev, group);

    static lv_indev_drv_t indev_drv_mw;
    lv_indev_drv_init(&indev_drv_mw); /*Basic initialization*/
    indev_drv_mw.type = LV_INDEV_TYPE_ENCODER;
    indev_drv_mw.read_cb = qt5_mousewheel_read;

    lv_indev_t *mw_indev = lv_indev_drv_register(&indev_drv_mw);
    lv_indev_set_group(mw_indev, group);

    /*Set a cursor for the mouse*/
    LV_IMG_DECLARE(mouse_cursor_icon); /*Declare the image file.*/
    lv_obj_t * cursor_obj = lv_img_create(lv_scr_act()); /*Create an image object for the cursor */
    lv_img_set_src(cursor_obj, &mouse_cursor_icon);           /*Set the image source*/
    lv_indev_set_cursor(mouse_indev, cursor_obj);             /*Connect the image  object to the driver*/

#endif // USE_QT5

#else
    /* This sets up some timers to handle everything. */
    windrv_init();
#endif // USE_WINDOWS
}
